
/*
*Released on 28th June 2008.
*Any violations can be reported at paritosh@wikiocean.net
*What is treated as violations can be found at www.wikiocean.net/ppl1-voilations*
******************************************************************************
* The contents of this file are subject to POOL Public License 1.0 and later.
* POOL Public License is based on Affero GPL v3 and additional conditions.
* ("License"); You may not use this file except in compliance with the License
* You may obtain a copy of the Affero GPL v3 License at http://www.gnu.org/licenses/agpl.html
* You may obtain a copy of the POOL Public License 1.0 or later at www.wikiocean.net/license/ppl.html
* Software distributed under POOL Public License 1.0 is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for
* the specific language governing rights and limitations under the License.
* The Initial Developer of the Original Code is Paritosh Pungaliya (C) 2008. All Rights Reserved.
******************************************************************************
* Objective of the additional terms (license)
* 1) Is to extend the software freedom to freedom to work.
* 2) To ensure that knowledge is free from monopoly of agencies.
* 3) To avoid a situation where big corporate or investor can buy out free software groups and companies and then start milking the communities built around it.
* (this trend can be seen how the freedom is curtailed in companies that get Venture Capital funding.)
******************************************************************************
*/

package  poolint.pull.tablename;

import java.sql.ResultSet;
import java.util.*;

import query.query.ParseQuery;
import control.RequestParameter;
import dbmanager.DBManager;
import dbmanager.DBOperation;
import dbmanager.GetIdName;

public abstract class IntegrateSubPool  implements IntegratePool
{
	String process = "";
	String request = ""; 
	String integrationObject;	
	String tidValue;	
	String tableName;
	//String columnName;
	//String columnValue;
	//String oldcolumnNameValue;
	
	Hashtable< Object, Object > columnNameValue = new Hashtable<Object, Object> ();
	Hashtable< Object, Object > oldColumnNameValue = new Hashtable<Object, Object> ();
	
	Hashtable<Object,Object> ModuleHash = new Hashtable<Object, Object>();
	Hashtable<Object, Object> productTableHash = new Hashtable<Object, Object>();
	
	String fieldList = "fieldlist";
	String field = "field";
	String column = "column";
	String tablist = "tablelist";
	String typeTable = "table";
	 String tableField = "tablename";
	
	RequestParameter req;
	DBOperation integratedDB;
	GetIdName gin;
	
	IntegrateSubPool integrate;
	
	public void setRequestParameter() 
	{
		req = new RequestParameter();	
		req.setUsername(userName);
		req.setPassword(password);
		req.setProcess(process);
		req.setVersion("11");
		req.setMessage("");
		req.setRequest(request);
		req.setProductName(gin.getItem(integrationObject));
	}
	
	public void setIntegrationObject(String integrationObject)
	{
		this.integrationObject = integrationObject;
	}
		
	public void setColumnNameValue( Hashtable< Object, Object > columnNameValue1 ) 
	{
		columnNameValue.putAll( columnNameValue1 );
		//this.columnName = columnName;
	}
	public IntegrateSubPool() {
		gin = new GetIdName();
	}
	
	/*public void setNewColumnValue(String newcolumnNameValue) 
	{
		this.columnValue = newcolumnNameValue;
	}*/

	public void setOldColumnNameValue( Hashtable< Object, Object > oldColumnNameValue1 ) 
	{
		oldColumnNameValue.putAll( oldColumnNameValue1 );
		//this.oldcolumnNameValue = oldcolumnNameValue;
	}

	public void setIntegratDatabase(DBOperation integrateDB) 
	{
		integratedDB = integrateDB;
	}

	public void setTableName(String tableName) 
	{
		this.tableName = tableName;
		
	}
	
	public void setProcess(String process) 
	{
		this.process = process;
	}
	
	public Hashtable<Object, Object> getFieldName()
	{
		Hashtable<Object, Object> columnFieldHash = new Hashtable<Object, Object>();
		
		String fieldId = gin.getId(field);
		String columnId = gin.getId(column);
		String fieldListId = gin.getId(fieldList);			
		String tableId = gin.getId(tableField);
		String tableNameId = gin.getId(tableName);
		
		Vector<Object> propPl = new Vector<Object>();
		propPl.add("property_details");
		Hashtable<Object, Object> condition = new Hashtable<Object, Object>();
		condition.put("Resultset", propPl);
		
		Vector<Object> joinVec = new Vector<Object>();
		Hashtable<Object, Object> joinHash = new Hashtable<Object, Object>();
		joinHash.put("LHS", "mid");
		joinHash.put("RHS", "mid");
		joinVec.add(joinHash);
		condition.put("Join", joinVec);
		
		Hashtable<Object, Object> condiHashOuter = new Hashtable<Object, Object>();
		condiHashOuter.put("pid", fieldId);
		condiHashOuter.put("logicaloperator", "AND");
		
	//	condition.put("Condition", condiVec);
		condition.put("Condition", getVectorPoolFormat("", condiHashOuter,true));
				
		Vector<Object> queryVec = new Vector<Object>();
			Hashtable<Object, Object> queryHash = new Hashtable<Object, Object>();
			queryHash.put("Resultset", propPl);
			
			Vector<Object> join1 = new Vector<Object>();
			Hashtable<Object, Object> joinHash1 = new Hashtable<Object, Object>();
			joinHash1.put("LHS", "pv");
			joinHash1.put("RHS", "mid");
			join1.add(joinHash1);
			queryHash.put("Join", join1);
			
			Enumeration<Object> keys = columnNameValue.keys();
			while(keys.hasMoreElements())
			{
				String columnName = keys.nextElement().toString();
				String columnNameId = gin.getId(columnName);

				Hashtable<Object, Object> condiInnerHash1 = new Hashtable<Object, Object>();
				condiInnerHash1.put(columnId, columnNameId);
				condiInnerHash1 = gin.ConvertKeytoMasterName(condiInnerHash1);
				condiInnerHash1 = gin.ConvertValuetoMasterName(condiInnerHash1);
				condiInnerHash1.put("logicaloperator","AND" );
					
				Vector<Object> condiVec3 = new Vector<Object>();
				condiVec3.add(condiHashOuter);
	
				queryHash.put("Condition", getVectorPoolFormat("", condiInnerHash1,true));
				
					Vector<Object> queryVec1 = new Vector<Object>();
					Hashtable<Object, Object> queryHashInner = new Hashtable<Object, Object>();
					queryHashInner.put("Resultset", propPl);
					
					Vector<Object> join2 = new Vector<Object>();
					Hashtable<Object, Object> joinHash2 = new Hashtable<Object, Object>();
					joinHash2.put("LHS", "pv");
					joinHash2.put("RHS", "mid");
					join2.add(joinHash2);
					queryHashInner.put("Join", join2);
					
					Hashtable<Object, Object> condiInnerHash2 = new Hashtable<Object, Object>();
					condiInnerHash2.put("pid", fieldId);
					condiInnerHash2.put("logicaloperator","AND" );
					
					queryHashInner.put("condition", getVectorPoolFormat("", condiInnerHash2,true));
					
					Vector<Object> queryVec2 = new Vector<Object>();
						Hashtable<Object, Object> queryHashInner1 = new Hashtable<Object, Object>();
						queryHashInner1.put("Resultset", propPl);
						
						Vector<Object> join3 = new Vector<Object>();
						Hashtable<Object, Object> joinHash3 = new Hashtable<Object, Object>();
						joinHash3.put("LHS", "mid");
						joinHash3.put("RHS", "mid");
						join3.add(joinHash3);
						queryHashInner1.put("Join", join3);
						
						Hashtable<Object, Object> condiInnerHash3 = new Hashtable<Object, Object>();
						condiInnerHash3.put("pid", fieldListId);
						condiInnerHash3.put("logicaloperator","AND" );
						
						queryHashInner1.put("Condition", getVectorPoolFormat("", condiInnerHash3,true));
						
						Vector<Object> queryVec3 = new Vector<Object>();
							Hashtable<Object, Object> queryHashInner2 = new Hashtable<Object, Object>();
							queryHashInner2.put("Resultset", propPl);
							
							Hashtable<Object, Object> condiInnerHash4 = new Hashtable<Object, Object>();
							condiInnerHash4.put(tableId,tableNameId);
							condiInnerHash4 = gin.ConvertKeytoMasterName(condiInnerHash4);
							condiInnerHash4 = gin.ConvertValuetoMasterName(condiInnerHash4);
							//condiInnerHash4.put("logicaloperator","AND" );
							
							queryHashInner2.put("Condition", getVectorPoolFormat("", condiInnerHash4,false));
							
							queryVec3.add(queryHashInner2);							
							queryHashInner1.put("Query", queryVec3);
							
						queryVec2.add(queryHashInner1);
						queryHashInner.put("Query", queryVec2);
						
					queryVec1.add(queryHashInner);
					queryHash.put("Query", queryVec1);
					
				queryVec.add(queryHash);
				condition.put("Query", queryVec);
				
				ParseQuery query = new ParseQuery();
				//query.SetTableName("master_table");
				//query.SetCondition(condition);
				Hashtable<Object, Object> tempFieldHash = new Hashtable<Object, Object>();
				tempFieldHash.put("field", "pv");		
				query.SetFieldList(tempFieldHash);
				query.SetQueryMap(condition);
				query.processQuery();
				String[] id = query.getbuffer();
				columnFieldHash.put(columnName, gin.getItem(id[1]));
			}
			return columnFieldHash;
	}
	
	/**getVectorPoolFormat() - converts hashtable into the Parse Query format. */
	private Vector<Object> getVectorPoolFormat(String master, Hashtable<Object, Object> property, boolean flag) 
	{
		Vector<Object> propertyVec = new Vector<Object>();
		Enumeration<Object> keys = property.keys();
		while(keys.hasMoreElements())
		{			
			String key = keys.nextElement().toString();
			String value = property.get(key).toString();
			if(key.equalsIgnoreCase("mid") || key.equalsIgnoreCase("pid") || key.equalsIgnoreCase("pv"))
			{
				Hashtable<Object, Object> temp = new Hashtable<Object, Object>();	
				temp.put("conditionfield", key);				
				temp.put("conditionvalue", value);
				temp.put("conditionoperator", "=");
				if(property.containsKey("logicaloperator"))
					temp.put("logicaloperator", property.get("logicaloperator"));
				propertyVec.add(temp);
			}	
			else  if(!key.equalsIgnoreCase("logicaloperator"))
			{
				Hashtable<Object, Object> temp = new Hashtable<Object, Object>();	
				temp.put("conditionfield", "pid");				
				temp.put("conditionvalue", gin.getId(key));
				temp.put("conditionoperator", "=");
				temp.put("logicaloperator", "and");
				Hashtable<Object, Object> temp1 = new Hashtable<Object, Object>();
				temp1.put("conditionfield", "pv");				
				temp1.put("conditionvalue", gin.getId(value));
				temp1.put("conditionoperator", "=");				
				if(flag)
					temp1.put("logicaloperator", property.get("logicaloperator"));
				propertyVec.add(temp);
				propertyVec.add(temp1);
			}
		
		}
		return propertyVec;
	}
	
	public String getColumnName(String joinObj,String fieldname) 
	{		
		//String columnName="";
		
		String fieldId = gin.getId(field);
		String columnId = gin.getId(column);
		String fieldListId = gin.getId(fieldList);			
		String fieldNameId = gin.getItem(fieldname); 
		//String JoinId = gin.getId(joinObj);		

		Hashtable<Object, Object> columnFieldHash = new Hashtable<Object, Object>();
		
		Vector<Object> propPl = new Vector<Object>();
		propPl.add("property_details");
		Hashtable<Object, Object> condition = new Hashtable<Object, Object>();
		condition.put("Resultset", propPl);
		
		Vector<Object> joinVec = new Vector<Object>();
		Hashtable<Object, Object> joinHash = new Hashtable<Object, Object>();
		joinHash.put("LHS", "mid");
		joinHash.put("RHS", "mid");
		joinVec.add(joinHash);
		condition.put("Join", joinVec);
		
		Hashtable<Object, Object> condiHashOuter = new Hashtable<Object, Object>();
		condiHashOuter.put("pid", columnId);
		condiHashOuter.put("logicaloperator", "AND");
		
	//	condition.put("Condition", condiVec);
		condition.put("Condition", getVectorPoolFormat("", condiHashOuter,true));
				
		Vector<Object> queryVec = new Vector<Object>();
			Hashtable<Object, Object> queryHash = new Hashtable<Object, Object>();
			queryHash.put("Resultset", propPl);
			
			Vector<Object> join1 = new Vector<Object>();
			Hashtable<Object, Object> joinHash1 = new Hashtable<Object, Object>();
			joinHash1.put("LHS", "pv");
			joinHash1.put("RHS", "mid");
			join1.add(joinHash1);
			queryHash.put("Join", join1);
			
				Hashtable<Object, Object> condiInnerHash1 = new Hashtable<Object, Object>();
				condiInnerHash1.put("pid", fieldListId);
				/*condiInnerHash1 = gin.ConvertKeytoMasterName(condiInnerHash1);
				condiInnerHash1 = gin.ConvertValuetoMasterName(condiInnerHash1);*/
				condiInnerHash1.put("logicaloperator","AND" );
					
				Vector<Object> condiVec3 = new Vector<Object>();
				condiVec3.add(condiHashOuter);
	
				queryHash.put("Condition", getVectorPoolFormat("", condiInnerHash1,true));
				
					Vector<Object> queryVec1 = new Vector<Object>();
					Hashtable<Object, Object> queryHashInner = new Hashtable<Object, Object>();
					queryHashInner.put("Resultset", propPl);
					
					Vector<Object> join2 = new Vector<Object>();
					Hashtable<Object, Object> joinHash2 = new Hashtable<Object, Object>();
					joinHash2.put("LHS", "pv");
					joinHash2.put("RHS", "mid");
					join2.add(joinHash2);
					queryHashInner.put("Join", join2);
					
					Hashtable<Object, Object> condiInnerHash2 = new Hashtable<Object, Object>();
					condiInnerHash2.put("pid", fieldId);
					condiInnerHash2.put("logicaloperator","AND" );
					
					queryHashInner.put("condition", getVectorPoolFormat("", condiInnerHash2,true));
					
					Vector<Object> queryVec2 = new Vector<Object>();
						Hashtable<Object, Object> queryHashInner1 = new Hashtable<Object, Object>();
						queryHashInner1.put("Resultset", propPl);
						
						Vector<Object> join3 = new Vector<Object>();
						Hashtable<Object, Object> joinHash3 = new Hashtable<Object, Object>();
						joinHash3.put("LHS", "mid");
						joinHash3.put("RHS", "mid");
						join3.add(joinHash3);
						queryHashInner1.put("Join", join3);
						
						Hashtable<Object, Object> condiInnerHash3 = new Hashtable<Object, Object>();
						condiInnerHash3.put(fieldId, fieldNameId);
						condiInnerHash3 = gin.ConvertKeytoMasterName(condiInnerHash3);
						condiInnerHash3 = gin.ConvertValuetoMasterName(condiInnerHash3);
						condiInnerHash3.put("logicaloperator","AND" );
										
						queryHashInner1.put("Condition", getVectorPoolFormat("", condiInnerHash3,true));
						
						Vector<Object> queryVec3 = new Vector<Object>();
							Hashtable<Object, Object> queryHashInner2 = new Hashtable<Object, Object>();
							queryHashInner2.put("Resultset", propPl);
							
							Hashtable<Object, Object> condiInnerHash4 = new Hashtable<Object, Object>();
							condiInnerHash4.put("pid", columnId);
							/*condiInnerHash4 = gin.ConvertKeytoMasterName(condiInnerHash4);
							condiInnerHash4 = gin.ConvertValuetoMasterName(condiInnerHash4);*/
							//condiInnerHash4.put("logicaloperator","AND" );
							
							queryHashInner2.put("Condition", getVectorPoolFormat("", condiInnerHash4,false));
							
							queryVec3.add(queryHashInner2);							
							queryHashInner1.put("Query", queryVec3);
							
						queryVec2.add(queryHashInner1);
						queryHashInner.put("Query", queryVec2);
						
					queryVec1.add(queryHashInner);
					queryHash.put("Query", queryVec1);
					
				queryVec.add(queryHash);
				condition.put("Query", queryVec);
				
				ParseQuery query = new ParseQuery();
				//query.SetTableName("master_table");
				//query.SetCondition(condition);
				Hashtable<Object, Object> tempFieldHash = new Hashtable<Object, Object>();
				tempFieldHash.put("field", "pv");		
				query.SetFieldList(tempFieldHash);
				query.SetQueryMap(condition);
				query.processQuery();
				String[] id = query.getbuffer();
				//columnFieldHash.put(columnName, gin.getItem(id[1]));
			
			return gin.getItem(id[1]);
	
		
		
		/*String query="SELECT p5.pv FROM property_details p1 JOIN (property_details p2 JOIN (property_details p3 JOIN (property_details p4 JOIN property_details p5 " +
					"ON (p4.mid = p5.mid)) ON (p3.pv = p4.mid)) ON (p2.pv = p3.mid)) ON (p1.mid = p2.mid) "+
					" WHERE p1.pv ='"+joinObj+"'  and p2.pid ='"+fieldListId+"' and p3.pid ='"+fieldId+"' and p4.pid ='"+fieldId+"' and p4.pv ='"+fieldname+"' and p5.pid = "+columnId;
		
		ResultSet rs= DBManager.getSelect(query);
		try 
		{
			rs.next();
			columnName=gin.getItem(rs.getString(1));	
			rs.close();
		} catch (Exception e) {
			e.printStackTrace();
		}
		return columnName;*/
	}
	
	
	public boolean isTransactionAvailable()
	{
		
		 String reflectSchemaProperty = "trans_property_details";
		boolean flag=false;
		//String field = getFieldName();
		/*
		String JoinId = gin.getId("join");
		String TableId = gin.getId("TABLE");
		String Tablenameid = gin.getId("TABLENAME");
		String TypeId = gin.getId("TYPE");		
		
		
		String query = "select p3.mid from property_details p3 JOIN (property_details p2 JOIN property_details p1 ON"
			+" (p2.pv=p1.mid)) ON (p3.mid=p2.mid) WHERE p3.pid='"+TypeId+"' AND p3.pv='"+JoinId+"' AND p2.pid='"+TableId+"' AND "
			+" p1.pid='"+Tablenameid+"' AND p1.pv='"+gin.getId(tableName)+"'";
		
		ResultSet rs= dbsql.getSelect(query);*/
		String LHSid = gin.getId("LHS");
		String joinTableObj="";
		ResultSet rs = getJoinResultSet();
		try 
		{
			rs.next();
			joinTableObj=rs.getString(1);	
			rs.close();
		} catch (Exception e) {
			return flag;
		}
		
		String query ="select pv from property_details where mid="+joinTableObj+" AND pid="+LHSid;			
		
		String fieldName;
		
		rs= DBManager.getSelect(query);
		try
		{
			rs.next();
			fieldName = rs.getString(1);	
	
			String colName = getColumnName(joinTableObj, fieldName);
			//columnName = gin.getItem(columnName);
			String value=gin.getId(productTableHash.get(colName).toString());
		/*	String masterValue = gin.getId(value);
			if(!(masterValue.equals("0")||masterValue.equals("no$")))
				query="select tid from "+reflectSchemaProperty+" where pid="+gin.getId(columnName)+" and pv='"+masterValue+"'";
			else
				query="select tid from "+reflectSchemaProperty+" where pid="+gin.getId(columnName)+" and vt='"+value+"'";
						
			 rs= DBManager.getSelect(query);		
			rs.next();
			tidValue=rs.getString(1);	
			rs.close(); */
			
			Hashtable<Object, Object> condition = new Hashtable<Object, Object>();
			condition.putAll(columnNameValue);
			
			// Assigns column value from Product table hash. 
			condition.put(colName, value);
			
			ParseQuery pquery = new ParseQuery();
			pquery.SetTableName("transaction");
			pquery.SetCondition(condition);
			Hashtable<Object, Object> tempFieldHash = new Hashtable<Object, Object>();
			tempFieldHash.put("field", "tid");		
			pquery.SetFieldList(tempFieldHash);
			pquery.processQuery();
			String[] id = pquery.getbuffer();
			
			if(id.length > 1)
				return flag=true;
		} 
		catch (Exception e)
		{ 
			e.printStackTrace();
			flag = false; 
		}		
		
		return flag;
	}
	
	
	public ResultSet getJoinResultSet() 
	{
		//String LHSid = gin.getId("LHS");
		String JoinId = gin.getId("join");
		String TableId = gin.getId("TABLE");
		String Tablenameid = gin.getId("TABLENAME");
		String TypeId = gin.getId("TYPE");		
		
	
		String query = "select p3.mid from property_details p3 JOIN (property_details p2 JOIN property_details p1 ON"
			+" (p2.pv=p1.mid)) ON (p3.mid=p2.mid) WHERE p3.pid='"+TypeId+"' AND p3.pv='"+JoinId+"' AND p2.pid='"+TableId+"' AND "
			+" p1.pid='"+Tablenameid+"' AND p1.pv='"+gin.getId(tableName)+"'";
		
		ResultSet rs= DBManager.getSelect(query);
		
		return rs;
	}
	
}
